<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>
    const data = [
      {id: '29', pid: '', name: '总裁办'},
      {id: '2c', pid: '', name: '财务部'},
      {id: '2d', pid: '2c', name: '财务核算部'},
      {id: '2f', pid: '2c', name: '薪资管理部'},
      {id: 'd2', pid: '', name: '技术部'},
      {id: 'd3', pid: 'd2', name: 'Java研发部'},
    ]

    const transform = params => {
      // obj 这个对象是用来方便我们查找元素的, 因为数组只能通过索引号查找
      // 而对象可以通过 key 键值对来查找元素
      const obj = {}

      // 第一个 forEach 循环: 
      // 判断数组对象中每一项对象里面的pid属性是否为空
      // 如果为空, 代表他是一级菜单, 那么就为对象添加一个 children 属性
      // 并将数组结构转化为对象的形式

      // 第二个 forEach 循环: 
      // 首先, 判断 pid 是否为空, 如果为空, 代表他是一级菜单, 如果 pid 有值, 就代表他是二级菜单
      // 如果 pid 有值代表item为二级菜单, 就将当前项 item 添加进一级菜单的 children 数组中
      // 如果 pid 没有值, 就代表 item 为一级菜单, 就将 一级菜单 添加进新建的专门用来存放一级菜单的数组中

      // 第一个 forEach 循环:
      params.forEach(item => {
        // 如果 对应项 pid 为空, 代表它是一级菜单, 就为 对应项的对象添加一个 children 空数组
        if (!item.pid) item.children = []
        // 将对应项的 id item.id属性作为 key键, 将每一项 item 作为值, 赋给空对象 obj 
        obj[item.id] = item
      })
      console.log(obj);

      // 定义一个空数组, 用于存放所有的一级菜单
      const newArr = []

      // 第二个forEach 循环:
      params.forEach(item => {
        // parent 可以找到 拥有二级菜单的当前项(一级菜单)
        // 例如, 当 当一级菜单当前项的 id 与二级菜单的 pid 相同, 那么就代表这个二级菜单是这个一级菜单的子菜单
        const parent = obj[item.pid]
        console.log(parent);
        // 如果 item.pid 有值, 就代表当前项是 二级菜单, 那么就将当前对象item
        if (item.pid) {
          parent.children.push(item)
        }
      })
    }

    transform(data)

  </script>
</body>
</html>